package com.cs410.collabwriting.junit.main;

import java.util.ArrayList;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestName;

import com.cs410.collabwriting.main.DatabaseObjects;
import com.cs410.collabwriting.main.Story;
import com.cs410.collabwriting.main.User;
import com.cs410.collabwriting.main.UserManager;
import com.cs410.collabwriting.test.DatabaseUtility;
import com.cs410.collabwriting.tools.LogManager;

import junit.framework.Assert;

public class UserManagerTest {

	@Rule
	public TestName m_testName = new TestName();
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		LogManager.logInfo("[JUnitTest] -- Starting JUnit Tests for UserManager" );
		DatabaseUtility.DeleteAllTables();
		Thread.sleep(1000);
		DatabaseUtility.CreateAllTables();
		Thread.sleep(1000);
		DatabaseUtility.CreateAllTestingData();
		Thread.sleep(15000);
		
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		DatabaseUtility.DeleteAllTables();
		LogManager.logInfo("[JUnitTest] -- Finished JUnit Tests for UserManager" );
	}

	@Before
	public void setUp() throws Exception {
		LogManager.logInfo("[JUnitTest] -- Starting Test : " + m_testName.getMethodName() );
	}

	@After
	public void tearDown() throws Exception {
		LogManager.logInfo("[JUnitTest] -- Finished Test : " + m_testName.getMethodName() );
	}

	@Test
	public void basicUserManagerInstanceTest() {
		UserManager uMan = UserManager.getInstance();
		Assert.assertNotNull( uMan );
	}
	
	@Test
	public void basicAddAndGetLoginUserTest() {
		UserManager uMan = UserManager.getInstance();
		String testUserAndPassAndEmail = m_testName.getMethodName();
		User user = uMan.addUser( testUserAndPassAndEmail, testUserAndPassAndEmail, testUserAndPassAndEmail);
		Assert.assertNotNull( user );
		
		user = uMan.getUser( user.getUserID() );
		Assert.assertNotNull( user );
		
		user.activateUser( user.getUserID(), user.getActivateKey() );
		user = UserManager.login( testUserAndPassAndEmail, testUserAndPassAndEmail );
		Assert.assertNotNull( user );
	}
	
	@Test
	public void basicUpdateTest() {
		UserManager uMan = UserManager.getInstance();
		Assert.assertNotNull( uMan );
		uMan.update();
	}
	
	@Test
	public void basicGetUserTest() {
		UserManager uMan = UserManager.getInstance();
		Assert.assertNotNull( uMan );
		
		User user = uMan.getUser("justine");
		Assert.assertNotNull( user );
		
		user = uMan.getUser("ABADFJSALKFJSLKAJFLKSADJFSA");
		Assert.assertNull( user );
	}
	
	@Test
	public void basicGetAllUsersTest() {
		UserManager uMan = UserManager.getInstance();
		ArrayList<DatabaseObjects> userList = uMan.getAll();
		Assert.assertNotNull( userList );
		Assert.assertTrue( userList.size() > 0 );
		
		for( DatabaseObjects user : userList ) {
			Assert.assertNotNull( user );
		}
	}
	
	@Test
	public void basicGetSubscribedStory() {
		UserManager uMan = UserManager.getInstance();
		ArrayList<DatabaseObjects> subStory = uMan.getSubscribedStories("username");
		Assert.assertNotNull( subStory );
		Assert.assertTrue( subStory.size() > 0 );
		
		subStory = uMan.getSubscribedStories("jslafjlsdflsajfa");
		Assert.assertNotNull( subStory );
		Assert.assertTrue( subStory.size() == 0 );
	}
	
	@Test
	public void basicGetSubscribedUser() {
		UserManager uMan = UserManager.getInstance();
		ArrayList<DatabaseObjects> subUser = uMan.getSubscribedUsers("justine");
		Assert.assertNotNull( subUser );
		Assert.assertTrue( subUser.size() > 0 );
		
		subUser = uMan.getSubscribedUsers("abasdfjsdfs");
		Assert.assertNotNull( subUser );
		Assert.assertTrue( subUser.size() == 0 );
	}
	
	@Test
	public void basicGetUserContributedStories() {
		UserManager uMan = UserManager.getInstance();
		ArrayList<Story> uStory = uMan.getUserContributedStories("angie");
		Assert.assertNotNull( uStory );
		Assert.assertTrue( uStory.size() > 0 );
	}
	
	@Test
	public void basicSubscribeUnsubscribeUser() {
		UserManager uMan = UserManager.getInstance();
		String userinfo = "12345usermantest";
		User user = uMan.addUser(userinfo,userinfo,userinfo);
		user.subscribeToWriter("justine");
		Assert.assertTrue( uMan.getSubscribedUsers( userinfo ).size() == 1 );
		uMan.unsubscribeFromUser( userinfo, "justine" );
		Assert.assertTrue( uMan.getSubscribedUsers( userinfo ).size() == 0 );
	}
	
	@Test
	public void basicSubscribeUnsubscribeStory() throws InterruptedException {
		UserManager uMan = UserManager.getInstance();
		String userinfo = "usermantest";
		User user = uMan.addUser(userinfo,userinfo,userinfo);
		user.subscribeToStory( 2 );
		Assert.assertTrue( uMan.getSubscribedStories( userinfo ).size() == 1 );
		uMan.unsubscribeFromStory( userinfo, Integer.toString(2) );
		Thread.sleep( 2000 );
		Assert.assertTrue( uMan.getSubscribedStories( userinfo ).size() == 0 );
	}
	
	@Test
	public void checkUserHasList() {
		UserManager uMan = UserManager.getInstance();
		boolean check = uMan.checkIfUserHasList("justine", "6231");
		Assert.assertFalse( check );
	}
}
